package org.sgx.gapi.client.apis.youtube;

import org.sgx.gapi.client.GAPI;
import org.sgx.gapi.client.client.ClientRequest;
import org.sgx.gapi.client.client.ClientRequestCallback;
import org.sgx.gapi.client.client.GAPICallback;
import org.sgx.gapi.client.client.GAPIListRequest;
import org.sgx.gapi.client.client.GAPIResult;
import org.sgx.gapi.client.client.HttpRequest;
import org.sgx.jsutil.client.JsObject;

/**
 * Returns a collection of search results that match the query parameters specified in the API request. By default, a search result set identifies matching video, channel, and playlist resources, but you can also configure queries to only retrieve a specific type of resource.
 * @see https://developers.google.com/youtube/v3/docs/search/list
 * TODO: comment getters & setters
 * @author sg
 * 
 */
public class SearchRequest /* implements GAPIRequest<SearchResponse> */
extends GAPIListRequest<SearchResponse> {
	String q, part, relatedToVideoId, channelId, order, publishedAfter, publishedBefore, regionCode, topicId, type, videoCaption, videoCategoryId, videoDefinition, videoDimension, videoDuration, videoEmbeddable, videoLicense, videoSyndicated;

	@Override
	public void execute(final GAPICallback<SearchResponse> c) {
		JsObject param = getListParams();
		if(part!=null)
			param.objPut("part", part);
		if(q!=null)
			param.objPut("q", q);
		if(type!=null)
			param.objPut("type", type); 
		//TODO: others
		ClientRequest clientReq = ClientRequest.create()
				.path("/youtube/v3/search")
				.params(param);
		HttpRequest req = GAPI.get().client().request(clientReq);
		req.execute(new ClientRequestCallback() {
			@Override
			public void call(GAPIResult jsonResp, String rawResp) {
				c.call((SearchResponse) jsonResp.cast());
			}
		});
	}

	/**
	 * The q parameter specifies the query term to search for.
	 * 
	 * @return
	 */
	public String getQ() {
		return q;
	}

	/**
	 * The q parameter specifies the query term to search for.
	 * 
	 * @param q
	 */
	public void setQ(String q) {
		this.q = q;
	}

	/**
	 * The part parameter specifies a comma-separated list of one or more search resource properties that the API response will include. The part names that you can include in the
	 * parameter value are id and snippet.
	 * 
	 * If the parameter identifies a property that contains child properties, the child properties will be included in the response. For example, in a search result, the snippet
	 * property contains other properties that identify the result's title, description, and so forth. If you set part=snippet, the API response will also contain all of those
	 * nested properties.
	 * 
	 * @return
	 */
	public String getPart() {
		return part;
	}

	/**
	 * The part parameter specifies a comma-separated list of one or more search resource properties that the API response will include. The part names that you can include in the
	 * parameter value are id and snippet.
	 * 
	 * If the parameter identifies a property that contains child properties, the child properties will be included in the response. For example, in a search result, the snippet
	 * property contains other properties that identify the result's title, description, and so forth. If you set part=snippet, the API response will also contain all of those
	 * nested properties.
	 * 
	 * @param part
	 */
	public void setPart(String part) {
		this.part = part;
	}

	/**
	 * 
	 * @return
	 */
	public String getRelatedToVideoId() {
		return relatedToVideoId;
	}

	/**
	 * 
	 * @param relatedToVideoId
	 */
	public void setRelatedToVideoId(String relatedToVideoId) {
		this.relatedToVideoId = relatedToVideoId;
	}

	/**
	 * The channelId parameter indicates that the API response should only contain resources created by the channel
	 * 
	 * @return
	 */
	public String getChannelId() {
		return channelId;
	}

	/**
	 * The channelId parameter indicates that the API response should only contain resources created by the channel
	 * 
	 * @param channelId
	 */
	public void setChannelId(String channelId) {
		this.channelId = channelId;
	}

	/**
	 * The <code><strong>order</strong></code> parameter specifies the method that will be used to order resources in the API response. The default value is
	 * <code>SEARCH_SORT_RELEVANCE</code>.<br>
	 * <br>
	 * Acceptable values are:
	 * <ul>
	 * <li><code><strong>date</strong></code> – Resources are sorted in reverse chronological order based on the date they were created.</li>
	 * <li><code><strong>rating</strong></code> – Resources are sorted from highest to lowest rating.</li>
	 * <li><code><strong>relevance</strong></code> – Resources are sorted based on their relevance to the search query. This is the default value for this parameter.</li>
	 * <li><code><strong>viewCount</strong></code> – Resources are sorted from highest to lowest number of views.</li>
	 * </ul>
	 * 
	 * @return
	 */
	public String getOrder() {
		return order;
	}

	/**
	 * The <code><strong>order</strong></code> parameter specifies the method that will be used to order resources in the API response. The default value is
	 * <code>SEARCH_SORT_RELEVANCE</code>.<br>
	 * <br>
	 * Acceptable values are:
	 * <ul>
	 * <li><code><strong>date</strong></code> – Resources are sorted in reverse chronological order based on the date they were created.</li>
	 * <li><code><strong>rating</strong></code> – Resources are sorted from highest to lowest rating.</li>
	 * <li><code><strong>relevance</strong></code> – Resources are sorted based on their relevance to the search query. This is the default value for this parameter.</li>
	 * <li><code><strong>viewCount</strong></code> – Resources are sorted from highest to lowest number of views.</li>
	 * </ul>
	 * 
	 * @param order
	 */
	public void setOrder(String order) {
		this.order = order;
	}

	public String getPublishedAfter() {
		return publishedAfter;
	}

	public void setPublishedAfter(String publishedAfter) {
		this.publishedAfter = publishedAfter;
	}

	public String getPublishedBefore() {
		return publishedBefore;
	}

	public void setPublishedBefore(String publishedBefore) {
		this.publishedBefore = publishedBefore;
	}

	public String getRegionCode() {
		return regionCode;
	}

	public void setRegionCode(String regionCode) {
		this.regionCode = regionCode;
	}

	public String getTopicId() {
		return topicId;
	}

	public void setTopicId(String topicId) {
		this.topicId = topicId;
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	public String getVideoCaption() {
		return videoCaption;
	}

	public void setVideoCaption(String videoCaption) {
		this.videoCaption = videoCaption;
	}

	public String getVideoCategoryId() {
		return videoCategoryId;
	}

	public void setVideoCategoryId(String videoCategoryId) {
		this.videoCategoryId = videoCategoryId;
	}

	public String getVideoDefinition() {
		return videoDefinition;
	}

	public void setVideoDefinition(String videoDefinition) {
		this.videoDefinition = videoDefinition;
	}

	public String getVideoDimension() {
		return videoDimension;
	}

	public void setVideoDimension(String videoDimension) {
		this.videoDimension = videoDimension;
	}

	public String getVideoDuration() {
		return videoDuration;
	}

	public void setVideoDuration(String videoDuration) {
		this.videoDuration = videoDuration;
	}

	public String getVideoEmbeddable() {
		return videoEmbeddable;
	}

	public void setVideoEmbeddable(String videoEmbeddable) {
		this.videoEmbeddable = videoEmbeddable;
	}

	public String getVideoLicense() {
		return videoLicense;
	}

	public void setVideoLicense(String videoLicense) {
		this.videoLicense = videoLicense;
	}

	public String getVideoSyndicated() {
		return videoSyndicated;
	}

	public void setVideoSyndicated(String videoSyndicated) {
		this.videoSyndicated = videoSyndicated;
	}

	
}
